﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Hawaii;
using Microsoft.Hawaii.Speech.Client;
using System.Windows.Threading;
using System.IO;
using Microsoft.Phone.Shell;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using System.Threading;
using Microsoft.Phone.Net.NetworkInformation;

namespace Enhanced_Hearing
{
    public partial class MainPage : PhoneApplicationPage
    {
        // varaibles
        private Boolean startStopText;
        private MemoryStream AudioStream { get; set; }
        private Microphone MicroPhone { get; set; }
        private byte[] AudioBuffer { get; set; }
        private int timer;
        private DispatcherTimer dispatchTimer;
        private ProgressIndicator statusBar;

        // Constructor
        public MainPage()
        {
            InitializeComponent();
            this.startStopText = true;
            this.AudioStream = new MemoryStream();
            this.MicroPhone = Microphone.Default;
            this.timer = 0;

            // Timer to simulate the XNA Framework game loop (Microphone is 
            // from the XNA Framework). We also use this timer to monitor the 
            // state of audio playback so we can update the UI appropriately.
            dispatchTimer = new DispatcherTimer();
            dispatchTimer.Interval = TimeSpan.FromMilliseconds(50);
            dispatchTimer.Tick += new EventHandler(this.DispatcherTimer_Tick);

            Thread.Sleep(750);
            

            // Event handler for getting audio data when the buffer is full
            this.MicroPhone.BufferReady += new EventHandler<EventArgs>(this.Microphone_BufferReady);    
        }


        /// <summary>
        /// Updates the XNA FrameworkDispatcher and checks to see if a sound is playing.
        /// If sound has stopped playing, it updates the UI.
        /// </summary>
        /// <param name="sender">
        /// Sender of this event.
        /// </param>
        /// <param name="e">
        /// Event arguments.
        /// </param>
        private void DispatcherTimer_Tick(object sender, EventArgs e)
        {
            FrameworkDispatcher.Update();
            this.timer++;
            if (this.timer >= 60)
            {
                this.MicroPhone.Stop();
                this.ProcessAudio();
                timer = 0;
            }
        }

        /// <summary>
        /// Event handler for buffer ready.
        /// </summary>
        /// <param name="sender">
        /// Sender of this event.
        /// </param>
        /// <param name="e">
        /// Event arguments.
        /// </param>
        private void Microphone_BufferReady(object sender, EventArgs e)
        {
            // Retrieve audio data
            this.MicroPhone.GetData(this.AudioBuffer);

            // Store the audio data in a stream
            this.AudioStream.Write(this.AudioBuffer, 0, this.AudioBuffer.Length);
        }

        private void ProcessAudio()
        {
            if (this.AudioStream != null && this.AudioStream.Length != 0)
            {
                SpeechService.RecognizeSpeechAsync(
                    HawaiiClient.HawaiiApplicationId,
                   "Dictation",
                this.AudioStream.ToArray(),
                (result) =>
                {
                    this.Dispatcher.BeginInvoke(() => this.OnSpeechRecognitionCompleted(result));
                });
            }
            this.startRecording();
        }

        private void OnSpeechRecognitionCompleted(SpeechServiceResult speechResult)
        {


            if (speechResult.Status == Status.Success)
            {

                if (speechResult.SpeechResult.Items.Count > 0)
                {
                    this.speech.Text = speechResult.SpeechResult.Items.ElementAt(0).ToString();
                    this.title.Text = "Enhanced Hearing - working...";
                }
                else
                {
                    this.title.Text = "Enhanced Hearing - unable to process last recording";
                }
            }
            else
            {
                MessageBox.Show("Error recognizing the speech.", "Error", MessageBoxButton.OK);
     
            }
        }

        private void startRecording()
        {
            // Get audio data in 1/2 second chunks
            this.MicroPhone.BufferDuration = TimeSpan.FromMilliseconds(500);

            // Allocate memory to hold the audio data
            this.AudioBuffer = new byte[this.MicroPhone.GetSampleSizeInBytes(this.MicroPhone.BufferDuration)];

            // Set the stream back to zero in case there is already something in it
            this.AudioStream.SetLength(0);
            this.MicroPhone.Start();
            this.timer = 0;
        }

        private void startStop_Click(object sender, RoutedEventArgs e)
        {
            

            // Update UI
            if (startStopText)
            {
                // Start recording
                startRecording();
                this.dispatchTimer.Start();
                startStopText = false;
                this.statusBar.IsVisible = true;
                SystemTray.SetProgressIndicator(this, this.statusBar);
                this.startStopBtn.Content = "Stop";
                this.speech.Text = "";
                this.title.Text = "Enhanced Hearing - working...";
            }
            else
            {
                // Stop recording
                this.MicroPhone.Stop();
                this.dispatchTimer.Stop();
                startStopText = true;
                this.statusBar.IsVisible = false;
                SystemTray.SetProgressIndicator(this, this.statusBar);
                this.startStopBtn.Content = "Start";
                this.title.Text = "Enhanced Hearing";
                this.speech.Text = "Press 'Start' to begin recording!";
            }
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            this.statusBar = new ProgressIndicator();
            this.statusBar.IsIndeterminate = true;
            this.statusBar.IsVisible = false;
            SystemTray.SetProgressIndicator(this, this.statusBar);


            if (!NetworkInterface.GetIsNetworkAvailable())
            {
                List<string> options = new List<string>();
                options.Add("Exit");
                IAsyncResult r = Guide.BeginShowMessageBox("Network Connection", "Your phone is not connected to the internet. This application requires the internet to run. Please restart the app and try again", options, 0, MessageBoxIcon.Alert, null, null);
                while (!r.IsCompleted)
                {
                    // Wait for user to press exit
                    Thread.Sleep(10);
                }
                // Exit app
                NavigationService.GoBack();
            }
        }

    }
}